/**
 * Copyright 2014 NAVER Corp.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * <p>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.apesay.plugins;


import com.apesay.core.ProfilerPlugin;
import javassist.*;

import java.util.HashMap;

/**
 * ClassName:MethodHandlePlugin2
 * Reason:	 
 * Date:     2017/10/27 11:09
 *
 * @author   sid
 */
public class MethodHandlePlugin2 implements ProfilerPlugin {
    static String beanName = "com.apesay.test.User";
    static String methodName = "isAdult";

    public void setup(Boolean open, HashMap<String, HashMap> clsMap) {
        if (open){
            System.out.println(MethodHandlePlugin2.class.getName()+" is used ");
            CtClass ctClass = addNewField();
            if (ctClass!=null)
                clsMap.get(TYPE_JAVASSIST).put(beanName,ctClass);
        }
    }


    private static CtClass  addNewField() {
        ClassPool classPool = ClassPool.getDefault();
        try {
            CtClass ctClass = classPool.get(beanName);
            //TODO 解冻
//            if (ctClass.isFrozen()){
//                ctClass.defrost();
//            }

            //TODO 2
            ctClass.addField(CtField.make("private long start2 = 0l;",ctClass));
            ctClass.addField(CtField.make("private long end2 = 0l;",ctClass));

            // 获取指定方法名称  
            CtMethod method = ctClass.getDeclaredMethod(methodName, null);
            CtMethod doBefor = CtNewMethod.make("public void doBefor2() {}", ctClass);
            doBefor.setBody("{" +
                    "this.start2 = System.currentTimeMillis();" +
                    "System.out.println(\"doBefor2-------MethodHandlePlugin2\");" +
                    "}");
            ctClass.addMethod(doBefor);
            CtMethod doAfter = CtNewMethod.make("public void doAfter2() {}", ctClass);
            doAfter.setBody("{" +
                    "this.end2 = System.currentTimeMillis();" +
                    "long consumeTime = this.end2 - this.start2;" +
//                    "System.out.println(consumeTime);" +
                    "System.out.println(\"doAfter2-------MethodHandlePlugin2：\"+consumeTime);" +
                    "}");
            ctClass.addMethod(doAfter);


            // 赋值方法到新方法中  
            CtMethod newMethod = CtNewMethod.copy(method, ctClass, null);
            // 修改源方法名称  
            String oldName = method.getName() + "$Impl2";
            method.setName(oldName);
            // 修改原方法  
            newMethod.setBody("{" +
                    "doBefor2();" +
                    "boolean obj = "+oldName+"($$);" +
                    "doAfter2();" +
                    "return obj;" +
                    "}");
            // 将新方法添加到类中  
            ctClass.addMethod(newMethod);
            //删除原来的方法
//            ctClass.removeMethod(method);
            // 加载重新编译的类  
//            ctClass.toClass();

            //TODO attempted  duplicate class definition for name: "com/apesay/test/User"
            return ctClass;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public String getKey() {
        return "method.handler2";
    }
}
